You have a list of integers, and for each index you want to find the product of every integer except the integer at that index.
Write a function get_products_of_all_ints_except_at_index() that takes a list of integers and returns a list of the products.
For example, given:
[1, 7, 3, 4]
your function would return:
[84, 12, 28, 21]
by calculating:
[7 * 3 * 4, 1 * 3 * 4, 1 * 7 * 4, 1 * 7 * 3]
Here's the catch: You can't use division in your solution!
To find the products of all the integers except the integer at each index, we'll go through our list greedily twice. First we get the products of all the integers before each index, and then we go backwards to get the products of all the integers after each index.
When we multiply all the products before and after each index, we get our answer—the products of all the integers except the integer at each index!
def get_products_of_all_ints_except_at_index(int_list):
if len(int_list) < 2:
raise IndexError('Getting the product of numbers at other '
'indices requires at least 2 numbers')
# We make a list with the length of the input list to
# hold our products
products_of_all_ints_except_at_index = [None] * len(int_list)
# For each integer, we find the product of all the integers
# before it, storing the total product so far each time
product_so_far = 1
for i in range(len(int_list)):
products_of_all_ints_except_at_index[i] = product_so_far
product_so_far *= int_list[i]
# For each integer, we find the product of all the integers
# after it. since each index in products already has the
# product of all the integers before it, now we're storing
# the total product of all other integers
product_so_far = 1
for i in range(len(int_list) - 1, -1, -1):
products_of_all_ints_except_at_index[i] *= product_so_far
product_so_far *= int_list[i]
return products_of_all_ints_except_at_index
time and space. We make two passes through our input a list, and the list we build always has the same length as the input list.
What if you could use division? Careful—watch out for zeroes!
Another question using a greedy approach. The tricky thing about this one: we couldn't actually solve it in one pass. But we could solve it in two passes!
This approach probably wouldn't have been obvious if we had started off trying to use a greedy approach.
Instead, we started off by coming up with a slow (but correct) brute force solution and trying to improve from there. We looked at what our solution actually calculated, step by step, and found some repeat work. Our final answer came from brainstorming ways to avoid doing that repeat work.
So that's a pattern that can be applied to other problems:
Start with a brute force solution, look for repeat work in that solution, and modify it to only do that work once.
Do you have an answer?
Wanna review this one again later? Or do you feel like you got it all?
Mark as done Pin for review laterReset editor
Powered by qualified.io